ページルート遷移をアニメーション化する
マテリアルなどの設計言語は、次の場合の標準的な動作を定義します。
ルート (または画面) 間の遷移。ただし、習慣として
画面間の遷移により、アプリをよりユニークにすることができます。助けるために、PageRouteBuilder
を提供しますAnimation
物体。
これAnimation
と一緒に使用できますTween
とCurve
オブジェクトを使用してトランジション アニメーションをカスタマイズします。
このレシピでは、次の間を移行する方法を示します。
新しいルートをアニメーション化してルートを表示します。
画面の下部。
カスタム ページのルート遷移を作成するために、このレシピでは次の手順を使用します。
- PageRouteBuilder をセットアップする
- を作成します
Tween
- を追加
AnimatedWidget
- 使う
CurveTween
- 2 つを組み合わせます
Tween
s
1. PageRouteBuilder をセットアップする
開始するには、PageRouteBuilder
を作成するRoute
。PageRouteBuilder
2 つのコールバックがあり、1 つはルートのコンテンツを構築するためのものです
(pageBuilder
)、もう 1 つはルートのトランジションを構築するためのもの (transitionsBuilder
)。
次の例では、2 つのルートを作成します。1 つは「Go!」の付いたホーム ルートです。ボタン、および 「ページ 2」というタイトルの 2 番目のルート。
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Page1(),
),
);
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(_createRoute());
},
child: const Text('Go!'),
),
),
);
}
}
Route _createRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return child;
},
);
}
class Page2 extends StatelessWidget {
const Page2({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: const Center(
child: Text('Page 2'),
),
);
}
}
2.トゥイーンを作成する
新しいページを下からアニメーション化するには、次からアニメーション化する必要があります。Offset(0,1)
にOffset(0, 0)
(通常は、Offset.zero
コンストラクタ)。この場合、オフセットは 2D ベクトルです。「分数翻訳」ウィジェット。
の設定dy
1 の引数は垂直方向の平行移動を表します
ページの高さ全体。
のtransitionsBuilder
コールバックにはanimation
パラメータ。それはAnimation<double>
0 から 1 までの値を生成します。
アニメーション
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return child;
},
3. AnimatedWidget を使用する
Flutterには拡張されたウィジェットのセットがありますAnimatedWidget
アニメーションの値が変更されると、自動的に再構築されます。例えば、
SlideTransition はAnimation<Offset>
そしてその子を翻訳します(
FractionalTranslation ウィジェット)、アニメーションの値が変更されるたびに。
AnimatedWidget を返すSlideTransition
とともにAnimation<Offset>
そして子ウィジェット:
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return SlideTransition(
position: offsetAnimation,
child: child,
);
},
4. CurveTween を使用する
Flutter は、イージング カーブの選択を提供します。
時間の経過に伴うアニメーションの速度を調整します。
のCurves
クラス
は、よく使用される曲線の事前定義されたセットを提供します。
例えば、Curves.easeOut
アニメーションを素早く開始し、ゆっくりと終了します。
カーブを使用するには、新しいカーブを作成しますCurveTween
そしてそれにCurveを渡します:
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
この新しいトゥイーンは引き続き 0 から 1 までの値を生成します。次のステップでは、次のようになります。
を組み合わせたTween<Offset>
ステップ2から。
5. 2 つのトゥイーンを結合します。
トゥイーンを組み合わせるには、
使用chain()
:
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
次に、このトゥイーンを次の関数に渡して使用します。animation.drive()
。これにより、新しいものが作成されますAnimation<Offset>
に与えることができるのはSlideTransition
ウィジェット:
return SlideTransition(
position: animation.drive(tween),
child: child,
);
この新しいトゥイーン (またはアニメーション可能) は、Offset
最初に評価して値を取得しますCurveTween
を評価し、Tween<Offset>.
アニメーションが実行されると、
値は次の順序で計算されます。
- アニメーション (transitionsBuilder コールバックに提供される) は値を生成します 0から1へ。
- CurveTween は、その値に基づいて、これらの値を 0 と 1 の間の新しい値にマップします。 曲線。
- の
Tween<Offset>
をマップしますdouble
に値するOffset
価値観。
を作成する別の方法Animation<Offset>
イージングカーブでは、CurvedAnimation
:
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
final tween = Tween(begin: begin, end: end);
final curvedAnimation = CurvedAnimation(
parent: animation,
curve: curve,
);
return SlideTransition(
position: tween.animate(curvedAnimation),
child: child,
);
}
インタラクティブな例
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Page1(),
),
);
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(_createRoute());
},
child: const Text('Go!'),
),
),
);
}
}
Route _createRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
class Page2 extends StatelessWidget {
const Page2({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: const Center(
child: Text('Page 2'),
),
);
}
}